import * as THREE from 'three'

/**
 * GPU拾取 - 用于高效的节点选择
 */
export class GPUPicking {
  constructor(renderer, camera, scene) {
    this.renderer = renderer
    this.camera = camera
    this.scene = scene
    
    // 创建拾取专用的渲染目标
    this.pickingTexture = new THREE.WebGLRenderTarget(1, 1)
    this.pickingTexture.texture.minFilter = THREE.NearestFilter
    this.pickingTexture.texture.magFilter = THREE.NearestFilter
    this.pickingTexture.texture.generateMipmaps = false
    
    // 拾取专用场景
    this.pickingScene = new THREE.Scene()
    
    // 像素缓冲区
    this.pixelBuffer = new Uint8Array(4)
    
    // 节点ID到对象的映射
    this.idToObject = new Map()
    this.nextId = 1
  }

  /**
   * 注册可拾取对象
   */
  registerObject(object, userData = {}) {
    const id = this.nextId++
    this.idToObject.set(id, { object, userData })
    
    // 创建拾取专用材质
    const pickingMaterial = new THREE.MeshBasicMaterial({
      color: new THREE.Color().setHex(id)
    })
    
    // 克隆几何体并应用拾取材质
    const pickingObject = object.clone()
    pickingObject.material = pickingMaterial
    pickingObject.userData.pickingId = id
    
    this.pickingScene.add(pickingObject)
    
    return id
  }

  /**
   * 执行拾取
   */
  pick(mouse) {
    // 更新拾取纹理大小
    const size = this.renderer.getSize(new THREE.Vector2())
    this.pickingTexture.setSize(size.width, size.height)
    
    // 渲染拾取场景
    this.renderer.setRenderTarget(this.pickingTexture)
    this.renderer.render(this.pickingScene, this.camera)
    
    // 读取鼠标位置的像素
    const x = Math.floor(mouse.x * size.width)
    const y = Math.floor((1 - mouse.y) * size.height)
    
    this.renderer.readRenderTargetPixels(
      this.pickingTexture, 
      x, y, 1, 1, 
      this.pixelBuffer
    )
    
    // 恢复默认渲染目标
    this.renderer.setRenderTarget(null)
    
    // 解析拾取的ID
    const id = (this.pixelBuffer[0] << 16) | (this.pixelBuffer[1] << 8) | this.pixelBuffer[2]
    
    return this.idToObject.get(id) || null
  }

  /**
   * 更新拾取场景中的对象位置
   */
  updateObject(id, position) {
    const entry = this.idToObject.get(id)
    if (entry) {
      const pickingObject = this.pickingScene.getObjectByProperty('userData.pickingId', id)
      if (pickingObject && position) {
        pickingObject.position.copy(position)
      }
    }
  }

  /**
   * 移除拾取对象
   */
  removeObject(id) {
    const entry = this.idToObject.get(id)
    if (entry) {
      const pickingObject = this.pickingScene.getObjectByProperty('userData.pickingId', id)
      if (pickingObject) {
        this.pickingScene.remove(pickingObject)
      }
      this.idToObject.delete(id)
    }
  }

  /**
   * 清空所有拾取对象
   */
  clear() {
    this.pickingScene.clear()
    this.idToObject.clear()
    this.nextId = 1
  }

  /**
   * 销毁资源
   */
  dispose() {
    this.pickingTexture.dispose()
    this.clear()
  }
}
